package com.css.zfzx.sjcj.common.spacedata;

import com.linuxense.javadbf.DBFReader;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.Filter;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

public class VectorDataUtil {

    public static String readPRJ(String path) {
        StringBuffer result = new StringBuffer();
        File file = new File(path);
        if (!file.exists()) return "";
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            while ((tempString = reader.readLine()) != null) {
                result.append(tempString);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString();
    }


    /*********************************DBF*************************************/

    public static String[] getFieldName(String path, String charsetName){
        try {
            DBFReader dbfReader = new DBFReader(new FileInputStream(path), Charset.forName(charsetName));
            int fieldCount = dbfReader.getFieldCount();//获取字段数量
            String[] fieldName = new String[fieldCount];
            for (int i = 0; i < fieldCount; i++) {
                fieldName[i] = dbfReader.getField(i).getName();
            }
            dbfReader.close();
            return fieldName;
        }catch(IOException ex){

        }
        return null;
    }

    /*
    public static String[] getFieldName(String path, String charsetName) throws IOException {
        DBFReader dbfReader = new DBFReader(new FileInputStream(path), Charset.forName(charsetName));
        int fieldCount = dbfReader.getFieldCount();//获取字段数量
        String[] fieldName = new String[fieldCount];
        for (int i = 0; i < fieldCount; i++) {
            fieldName[i] = dbfReader.getField(i).getName();
        }
        dbfReader.close();
        return fieldName;
    }

     */

    public static ArrayList<Object[]> getFieldValue(String path, String charsetName) throws IOException {
        ArrayList<Object[]> result = new ArrayList<Object[]>();
        DBFReader dbfReader = new DBFReader(new FileInputStream(path), Charset.forName(charsetName));
        Object[] rowValues;
        while ((rowValues = dbfReader.nextRecord()) != null) {
            result.add(rowValues);
        }
        dbfReader.close();
        return result;
    }

    public static SimpleFeatureCollection readDBF(String path,int type) {
        return readShp(path, null,type);
    }

    public static SimpleFeatureCollection readDBF(String path, Filter filter,int type) {
        SimpleFeatureSource featureSource = readStoreByDBF(path,type);
        if (featureSource == null) return null;
        try {
            return filter != null ? featureSource.getFeatures(filter) : featureSource.getFeatures();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static SimpleFeatureSource readStoreByDBF(String path,int type) {
        File file = new File(path);
        FileDataStore store;
        SimpleFeatureSource featureSource = null;
        try {
            store = FileDataStoreFinder.getDataStore(file);
            ((ShapefileDataStore) store).setCharset(Charset.forName("GBK"));
            if(type==1){
                ((ShapefileDataStore) store).setCharset(Charset.forName("UTF-8"));
            }
            featureSource = store.getFeatureSource();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return featureSource;
    }

    /*********************************DBF*********END****************************/


    /*********************************SHP*************************************/


    private static SimpleFeatureIterator getSimpleFeatureIterator(SimpleFeatureCollection colls1){
        try{
            SimpleFeatureIterator iters = colls1.features();
            return iters;
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static List<List<Object>> readSHPFile(String path,int type) {
        String prjPath = path.substring(0, path.length() - 4) + ".prj";
        //String testPath = path.substring(0, path.length() - 4) + ".dbf";
        //String code = getFileEncode(testPath);
        String strWKTMercator = readPRJ(prjPath);
       if(!strWKTMercator.contains("CGCS2000")){
            throw new RuntimeException("SHP数据坐标系必须是CGCS2000坐标系");
        }
        if (strWKTMercator != "") ProjectTransUtil.setStrWKTMercator(strWKTMercator);
        SimpleFeatureCollection colls1 = readShp(path,type);
        SimpleFeatureIterator iters=getSimpleFeatureIterator(colls1);
        if(iters==null){
            int typetype=0;
            if(type==0){
                typetype=1;
            }
            colls1 = readShp(path,typetype);
            iters=getSimpleFeatureIterator(colls1);
        }
        /*try{
            iters = colls1.features();
        }
        catch (Exception e){
            e.printStackTrace();
        }*/
        List<List<Object>> result = new ArrayList<List<Object>>();
        while (iters.hasNext()) {
            SimpleFeature sf = iters.next();
            List<Object> attributes = sf.getAttributes();
            String lonlatStr = ProjectTransUtil.wktPolygon2Lonlat(attributes.get(0).toString());
            attributes.set(0, lonlatStr);
            result.add(attributes);
        }
        return result;
    }

    public static SimpleFeatureCollection readShp(String path,int type) {
        return readShp(path, null,type);
    }

    public static SimpleFeatureCollection readShp(String path, Filter filter,int type) {
        SimpleFeatureSource featureSource = readStoreByShp(path,type);
        if (featureSource == null) return null;
        try {
            return filter != null ? featureSource.getFeatures(filter) : featureSource.getFeatures();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getFileEncode(String path) {
        String charset ="asci";
        byte[] first3Bytes = new byte[3];
        BufferedInputStream bis = null;
        try {
            boolean checked = false;
            bis = new BufferedInputStream(new FileInputStream(path));
            bis.mark(0);
            int read = bis.read(first3Bytes, 0, 3);
            if (read == -1)
                return charset;
            if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
                charset = "Unicode";//UTF-16LE
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF) {
                charset = "Unicode";//UTF-16BE
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB && first3Bytes[2] == (byte) 0xBF) {
                charset = "UTF8";
                checked = true;
            }
            bis.reset();
            if (!checked) {
                int len = 0;
                int loc = 0;
                while ((read = bis.read()) != -1) {
                    loc++;
                    if (read >= 0xF0)
                        break;
                    if (0x80 <= read && read <= 0xBF) //单独出现BF以下的，也算是GBK
                        break;
                    if (0xC0 <= read && read <= 0xDF) {
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF)
                            //双字节 (0xC0 - 0xDF) (0x80 - 0xBF),也可能在GB编码内
                            continue;
                        else
                            break;
                    } else if (0xE0 <= read && read <= 0xEF) { //也有可能出错，但是几率较小
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF) {
                            read = bis.read();
                            if (0x80 <= read && read <= 0xBF) {
                                charset = "UTF-8";
                                break;
                            } else
                                break;
                        } else
                            break;
                    }
                }
                //TextLogger.getLogger().info(loc + " " + Integer.toHexString(read));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException ex) {
                }
            }
        }
        return charset;
    }

    private static String getEncode(int flag1, int flag2, int flag3) {
        String encode = "";
        // txt文件的开头会多出几个字节，分别是FF、FE（Unicode）,
        // FE、FF（Unicode big endian）,EF、BB、BF（UTF-8）
        if (flag1 == 255 && flag2 == 254) {
            encode = "Unicode";
        } else if (flag1 == 254 && flag2 == 255) {
            encode = "UTF-16";
        } else if (flag1 == 239 && flag2 == 187 && flag3 == 191) {
            encode = "UTF8";
        } else {
            encode = "asci";// ASCII码
        }
        return encode;
    }

        public static SimpleFeatureSource readStoreByShp(String path,int type) {
        File file = new File(path);
        FileDataStore store;
        SimpleFeatureSource featureSource = null;
        try {
            store = FileDataStoreFinder.getDataStore(file);
            ((ShapefileDataStore) store).setCharset(Charset.forName("GBK"));
            if(type==1){
                ((ShapefileDataStore) store).setCharset(Charset.forName("UTF-8"));
            }
            featureSource = store.getFeatureSource();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return featureSource;
    }
    /*********************************SHP*********END****************************/

    public static List<List<Object>> readSHPFile2(File file) {
        /*
        String path = file.getName();
        String prjPath = path.substring(0, path.length() - 4) + ".prj";
        String strWKTMercator = readPRJ(prjPath);
        if (strWKTMercator != "") ProjectTransUtil.setStrWKTMercator(strWKTMercator);
         */
        SimpleFeatureCollection colls1 = readShp2(file);
        SimpleFeatureIterator iters = colls1.features();
        List<List<Object>> result = new ArrayList<List<Object>>();
        while (iters.hasNext()) {
            SimpleFeature sf = iters.next();
            List<Object> attributes = sf.getAttributes();
            String lonlatStr = ProjectTransUtil.wktPolygon2Lonlat(attributes.get(0).toString());
            attributes.set(0, lonlatStr);
            result.add(attributes);
        }
        return result;
    }
    public static SimpleFeatureCollection readShp2(File file) {
        return readShp2(file, null);
    }
    public static SimpleFeatureCollection readShp2(File file, Filter filter) {
        SimpleFeatureSource featureSource = readStoreByShp2(file);
        if (featureSource == null) return null;
        try {
            return filter != null ? featureSource.getFeatures(filter) : featureSource.getFeatures();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static SimpleFeatureSource readStoreByShp2(File file) {
        FileDataStore store;
        SimpleFeatureSource featureSource = null;
        try {
            store = FileDataStoreFinder.getDataStore(file);
            ((ShapefileDataStore) store).setCharset(Charset.forName("GBK"));
            featureSource = store.getFeatureSource();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return featureSource;
    }












    public static void testReadDBF(String path) {
        String path1 = "E:\\IdeaProjects\\zfzx文档\\风险评估\\预评估\\预评估工作区范围样例数据-矢量数据\\甘青川地震危险区.dbf";

        try {
            ArrayList<Object[]> result = getFieldValue(path1, "GBK");
            for (int i = 0; i < result.size(); i++) {
                Object[] res = result.get(i);
                for (int j = 0; j < res.length; j++) {
                    System.out.println(res[j]);
                }
                System.out.println("======================");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void testReadSHP() {
        String path = "E:\\IdeaProjects\\zfzx文档\\风险评估\\To开发\\预评估\\预评估工作区范围样例数据-矢量数据\\甘青川地震危险区.shp";
        List<List<Object>> res = readSHPFile(path,0);
        System.out.println(res);
    }

    public static void testReadPRJ() {
        String prjPath = "E:\\IdeaProjects\\zfzx文档\\风险评估\\To开发\\预评估\\预评估工作区范围样例数据-矢量数据\\甘宁陕地震危险区.prj";
        System.out.println(VectorDataUtil.readPRJ(prjPath));
    }

    public static void main(String[] args) {

        testReadSHP();

        //testReadPRJ();

    }

    public static void inputStreamToFile(InputStream ins, File file, int len) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[len];
            while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
